﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.SessionState;
using Microsoft.Practices.Unity;
using System.Web.UI;
using Microsoft.Practices.Unity.Configuration;
using System.Web.Configuration;
using System.Threading;
using System.Globalization;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
using System.Configuration;
using System.Reflection;
using System.IO;
using DreamBuilder.Core.Container;
using DreamBuilder.Core.Quartz;
using DreamBuilder.Core.Message;
using Web.SystemLogin.Models;
using Web.SystemConfig.Services;
using Web.SystemLogin.Business;
using DreamBuilder.Core.Log;
using System.Timers;
using System.Collections;


namespace Web
{
    public class Global : System.Web.HttpApplication
    {
        private static readonly string ERROR_PAGE_LOCATION = "~/ErrorPage.aspx";
        private const string Quartz_Server = "Quartz_Server";
        private Hashtable ht = new Hashtable();
        private static System.Timers.Timer timer = null;

        protected void Application_Start(object sender, EventArgs e)
        {
            ///初始化工作流配置
            SystemConfig.SysCache.ArchiveCacheFacade cacheFacade = new SystemConfig.SysCache.ArchiveCacheFacade();
            cacheFacade.Init();

            if (Thread.CurrentThread.CurrentCulture.Name != "zh-CN")
            {
                Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("zh-CN");
            }
            //初始化容器
            IUnityContainer applicationContainer = new UnityContainer();
            FileConfigurationSource containerConfig = new FileConfigurationSource(RootConfigurationFilePath(ConfigurationManager.AppSettings["ContainerConfigPath"]));
            UContainer.ConfigureContainer(applicationContainer, ContainerName.Application, containerConfig);
            ApplicationContainer = applicationContainer;
            UContainer.Container = ApplicationContainer;

            //工作流流程初始化
            //FlowConfig.Initialization(AppDomain.CurrentDomain.BaseDirectory + "Config\\WFConfig.xml");

            //统计在线人数
            Application["User_OnLine"] = 0;
            Application["User_Sission"] = ht;
            ////启动quartz
            //IQuartzServer quartzServer = QuartzServerFactory.CreateServer();
            //quartzServer.Initialize();
            //quartzServer.Start();
            //QuartzServer = quartzServer;
        }


        private string RootConfigurationFilePath(string configurationFile)
        {
            string rootedConfigurationFile = (string)configurationFile.Clone();
            if (!Path.IsPathRooted(rootedConfigurationFile))
            {
                rootedConfigurationFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, rootedConfigurationFile);
            }
            return rootedConfigurationFile;
        }


        void CurrentDomain_DomainUnload(object sender, EventArgs e)
        {
            //AppDomain.CurrentDomain.assem
        }


        protected void Application_End(object sender, EventArgs e)
        {
            IUnityContainer applicationContainer = this.ApplicationContainer;

            if (applicationContainer != null)
            {
                applicationContainer.Dispose();

                this.ApplicationContainer = null;
            }

            //关闭quartz
            IQuartzServer quartzServer = QuartzServer;
            if (quartzServer != null)
            {
                quartzServer.Stop();
            }
        }

        protected void Application_Error(Object sender, EventArgs e)
        {
        //    try
        //    {
        //        Exception loLastError = this.Server.GetLastError();
        //        //Use Application object may be existed some defects
        //        if (loLastError is MessageInfo)
        //            this.Application[DreamBuilder.Core.Message.MessageInfo.AppMsgKey] = loLastError;
        //        else
        //            this.Application[MessageInfo.AppMsgKey] = MessageHandler.CreateMessage(loLastError);
        //        this.Response.Redirect(ERROR_PAGE_LOCATION);
        //    }
        //    catch
        //    {
        //    }
            //this.Response.Redirect(this.Request.Url.AbsoluteUri);
        }



        protected void Application_PreRequestHandlerExecute(object sender, EventArgs e)
        {
            Page handler = HttpContext.Current.Handler as Page;
            if (handler != null)
            {
                IUnityContainer container = ApplicationContainer;

                if (container != null)
                {
                    container.BuildUp(handler.GetType(), handler);
                    handler.PreLoad += currentPage_PreLoad;

                }

            }
        }
        /// <summary>
        /// 页面加载之前容器和用户控件绑定
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void currentPage_PreLoad(object sender, System.EventArgs e)
        {
            Page page = HttpContext.Current.CurrentHandler as Page;
            if (page != null)
            {
                InjectUserControls(page);
            }
        }

        private void InjectUserControls(Control currentControl)
        {
            foreach (Control control in currentControl.Controls)
            {
                if (control is UserControl)
                {
                    ApplicationContainer.BuildUp(control.GetType(), control);
                }
                InjectUserControls(control);
            }
        }


        protected void Session_Start(object sender, EventArgs e)
        {
            Session.Timeout = 30;
            if (this.Application["PhysicalApplicationPath_1"] == null)
            {
                this.Application["PhysicalApplicationPath_1"] = this.Request.PhysicalApplicationPath;
            }
        }


        protected void Application_BeginRequest(object sender, EventArgs e)
        {
            /* Fix for the Flash Player Cookie bug in Non-IE browsers.
            * Since Flash Player always sends the IE cookies even in FireFox
            * we have to bypass the cookies by sending the values as part of the POST or GET
            * and overwrite the cookies with the passed in values.
            *
            * The theory is that at this point (BeginRequest) the cookies have not been ready by
            * the Session and Authentication logic and if we update the cookies here we'll get our
            * Session and Authentication restored correctly
            */
            if (Request.Cookies["Resource"] != null)
            {
                Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(Request.Cookies["Resource"].Value);
                Thread.CurrentThread.CurrentUICulture = Thread.CurrentThread.CurrentCulture;
            }
            try
            {
                string session_param_name = "ASPSESSID";
                string session_cookie_name = "ASP.NET_SESSIONID";

                if (HttpContext.Current.Request.Form[session_param_name] != null)
                {
                    UpdateCookie(session_cookie_name, HttpContext.Current.Request.Form[session_param_name]);
                }
                else if (HttpContext.Current.Request.QueryString[session_param_name] != null)
                {
                    UpdateCookie(session_cookie_name, HttpContext.Current.Request.QueryString[session_param_name]);
                }
            }
            catch (Exception)
            {
            }

            try
            {
                string auth_param_name = "AUTHID";
                string auth_cookie_name = FormsAuthentication.FormsCookieName;

                if (HttpContext.Current.Request.Form[auth_param_name] != null)
                {
                    UpdateCookie(auth_cookie_name, HttpContext.Current.Request.Form[auth_param_name]);
                }
                else if (HttpContext.Current.Request.QueryString[auth_param_name] != null)
                {
                    UpdateCookie(auth_cookie_name, HttpContext.Current.Request.QueryString[auth_param_name]);
                }

            }
            catch (Exception)
            {
            }
        }
        protected void UpdateCookie(string cookie_name, string cookie_value)
        {
            HttpCookie cookie = HttpContext.Current.Request.Cookies.Get(cookie_name);
            if (cookie == null)
            {
                HttpCookie cookie1 = new HttpCookie(cookie_name, cookie_value);
                Response.Cookies.Add(cookie1);
            }
            else
            {
                cookie.Value = cookie_value;
                HttpContext.Current.Request.Cookies.Set(cookie);
            }
        }

        //protected void Application_BeginRequest(object sender, EventArgs e)
        //{
        //    if (Request.Cookies["Resource"] != null)
        //    {
        //        Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(Request.Cookies["Resource"].Value);
        //        Thread.CurrentThread.CurrentUICulture = Thread.CurrentThread.CurrentCulture;
        //    }
        //}


        protected void Session_End(object sender, EventArgs e)
        {
            // 在会话结束时运行的代码。 
            // 注意: 只有在 Web.config 文件中的 sessionstate 模式设置为
            // InProc 时，才会引发 Session_End 事件。如果会话模式设置为 StateServer 
            // 或 SQLServer，则不会引发该事件。
            //PopOnlineUser();
            //检查是否有多次登陆的，有多次登陆的人，恢复在线状态
            //if (timer == null)
            //{
            //    timer = new System.Timers.Timer();
            //    timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);
            //    timer.Interval = 60000;
            //    timer.Start();
            //}
            try
            {
                if (this.Application["PhysicalApplicationPath_1"] != null)
                {
                    string path = Path.Combine(this.Application["PhysicalApplicationPath_1"].ToString(), "TempDatas");
                    path = Path.Combine(path, this.Session.SessionID);
                    if (Directory.Exists(path))
                    {
                        Directory.Delete(path, true);
                    }
                }
            }
            catch
            { }
        }

        protected void Application_AcquireRequestState(object sender, EventArgs e)
        {
        }

        private IUnityContainer ApplicationContainer
        {
            get
            {
                return (IUnityContainer)this.Application[ContainerKey.AppContainerKey];
            }
            set
            {
                this.Application[ContainerKey.AppContainerKey] = value;
            }
        }

        private IUnityContainer SessionContainer
        {
            get
            {
                return (IUnityContainer)this.Session[ContainerKey.SessionContainerKey];
            }
            set
            {
                this.Session[ContainerKey.SessionContainerKey] = value;
            }
        }

        private IQuartzServer QuartzServer
        {
            get
            {
                return (IQuartzServer)this.Application[Quartz_Server];
            }
            set
            {
                this.Application[Quartz_Server] = value;
            }
        }

        /// <summary>
        /// 删除存储当前用户的Session，修改用户在线状态
        /// </summary>
        private void PopOnlineUser()
        {
            Application.Lock();
            Hashtable ht = (Hashtable)Application["User_Sission"];
            User user = (User)ht[Session.SessionID];
            ht.Remove(Session.SessionID);
            IAuth_User SystemConfigComponent = UContainer.Resolve<IAuth_User>();
            //将Application中的用户和数据库中的进行比对，刷新状态(为离线)
            SystemConfigComponent.UpdateUserState(user.User_ID, user.Real_ID, user.LoginPatform, user.LoginIp, user.LoginBrowers, false);
            Application["User_Sission"] = ht;
            //记录日志
            #region 记录登录日志
            OnlineUser ou = new OnlineUser();
            ILogger log = UContainer.Resolve<ILogger>(Category.LogoutLog);
            log.Info(ou.GetLogInfo(user.User_ID,user.User_Name, user.LoginIp, user.LoginPatform, Thread.CurrentThread.CurrentUICulture.Name, user.LoginBrowers));
            #endregion
            Application.UnLock();
        }

        private void timer_Elapsed(object sender, ElapsedEventArgs e)
        {
            Application.Lock();
            //删除Application中的对象，记录日志
            Hashtable ht = (Hashtable)Application["User_Sission"];
            foreach (User user in ht)
            {
                IAuth_User SystemConfigComponent = UContainer.Resolve<IAuth_User>();
                //将Application中的用户和数据库中的进行比对，刷新状态
                SystemConfigComponent.UpdateUserState(user.User_ID, user.Real_ID, user.LoginPatform, user.LoginIp, user.LoginBrowers, true);
            }
            Application.UnLock();
        }
    }
}
